#!/usr/bin/env python

"A simple web page compiler"

import sys
from os import listdir, chdir, system
from os.path import isfile, isdir, realpath
from argparse import ArgumentParser
from json import loads as json_loads
from mistune import html as md2html
from csscompressor import compress as cssmin
from jsmin import jsmin


TAGS = {
    "CSS": '<style>{code}</style>',
    "JS": '<script>{code}</script>'
}


def render_page(template: str, **kwargs) -> str:
    "Render the page to make a static file"
    file = open(file=template, mode='r', encoding='utf-8')
    result = file.read()
    file.close()
    result = result.format(**kwargs)
    return result


def create_static_css(file: str) -> str:
    "Create an tag to save CSS minified"
    css_file = open(file=file, mode='r', encoding='utf-8')
    css_min = cssmin(css_file.read())
    css_file.close()
    result = TAGS['CSS'].format(code=css_min)
    return result


def create_static_js(file: str) -> str:
    "Create and ta to save JavaScript minified"
    js_file = open(file=file, mode='r', encoding='utf-8')
    js_min = jsmin(js_file.read())
    js_file.close()
    result = TAGS['JS'].format(code=js_min)
    return result


def compile_page(template: str, folder: str, output: str):
    "Compile the complete page and show it on stdout"
    print(f"Compiling {folder.split('/')[-1]}...", end='')
    chdir(folder)
    if isfile('precompile.py'):
        system('python precompile.py')
    info_file = open(file='info.json', mode='r', encoding='utf-8')
    informations = json_loads(info_file.read())
    info_file.close()
    styles = ""
    for style in informations['imports']['css']:
        styles += create_static_css(style)
    scripts = ""
    for script in informations['imports']['js']:
        scripts += create_static_js(script)
    content_file = open(file='index.md', mode='r', encoding='utf-8')
    content = md2html(content_file.read())
    content_file.close()
    result = render_page(
        template,
        styles=styles,
        content=content,
        scripts=scripts,
        **informations
    )
    out = open(output, 'w')
    out.write(result)
    out.flush()
    out.close()
    if isfile('postcompile.py'):
        system('python postcompile.py')
    print(" Done")


def find_pages(main_folder: str):
    chdir(main_folder)
    result = []
    if isfile('info.json'):
        result.append(realpath('.'))
    folders = listdir()
    for folder in folders:
        if isdir(folder):
            any(map(lambda a: result.append(a), find_pages(folder)))
    chdir('..')
    return result


def compile_all(template: str, output: str, folders: list):
    output = output.split('/')[-1]
    for folder in folders:
        compile_page(template, folder, output)


if __name__ == '__main__':
    args = ArgumentParser()
    args.add_argument(
        '-t', '--template',
        help='Template of the output'
    )
    args.add_argument(
        '-f', '--folder',
        help='The folder of page to compile'
    )
    args.add_argument(
        '-o', '--output',
        help='Output file name'
    )
    args.add_argument(
        '-a', '--all',
        help='Compile all pages encountred in the subfolders',
        action="store_const",
        const=True
    )
    arg = args.parse_args()
    if arg.template and arg.folder and arg.output and arg.all:
        pages = find_pages(arg.folder)
        compile_all(realpath(arg.template), arg.output, pages)
    elif arg.template and arg.folder and arg.output:
        compile_page(arg.template, arg.folder, arg.output)
    sys.exit(0)
